package com.lianqi.emcpframework.design.domain.event;

/**
 * @program emcp-framework
 * @ClassName DomainEventHandlerRegistry
 * @description: 领域事件处理器注册接口
 * @author: sky
 * @create: 2019/06/06 10:31
 */
public interface DomainEventHandlerRegistry {

    /**
     * 注册领域事件
     * 
     * @param subscriber
     *            事件订阅者
     * @param handler
     *            事件handler
     * @param <E>
     *            领域事件泛型
     * 
     */
    default <E extends DomainEvent> void register(DomainEventSubscriber<E> subscriber, DomainEventHandler<E> handler) {
        register(subscriber, new DomainEventExecutor.SyncExecutor(), handler);
    }

    /**
     * 注册领域事件
     * 
     * @param eventClass
     *            领域事件类型
     * @param handler
     *            领域事件handler
     * @param <E>
     *            领域事件泛型
     */
    default <E extends DomainEvent> void register(Class<E> eventClass, DomainEventHandler<E> handler) {
        register(event -> event.getClass() == eventClass, new DomainEventExecutor.SyncExecutor(), handler);
    }

    /**
     * 注册领域事件
     * 
     * @param eventClass
     *            领域事件类型
     * @param executor
     *            领域事件执行器
     * @param handler
     *            领域事件handler
     * @param <E>
     *            领域事件泛型
     */
    default <E extends DomainEvent> void register(Class<E> eventClass, DomainEventExecutor executor,
        DomainEventHandler<E> handler) {
        register(event -> event.getClass() == eventClass, executor, handler);
    }

    /**
     * 注册事件处理器 并指定事件执行器
     * 
     * @param subscriber
     *            事件订阅
     * @param executor
     *            事件执行器
     * @param handler
     *            事件处理器
     * @param <E>
     *            事件泛型
     */
    <E extends DomainEvent> void register(DomainEventSubscriber<E> subscriber, DomainEventExecutor executor,
        DomainEventHandler<E> handler);

    /**
     * 注销事件
     * 
     * @param subscriber
     *            事件订阅者
     * @param <E>
     *            事件泛型
     */
    <E extends DomainEvent> void unregister(DomainEventSubscriber<E> subscriber);

    /**
     * 注销事件
     * 
     * @param handler
     *            事件处理器
     * @param <E>
     *            事件泛型
     */
    <E extends DomainEvent> void unregisterAll(DomainEventHandler<E> handler);
}
